package com.harvest.scientific.ladder.base

import android.content.Context
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import androidx.annotation.CallSuper
import androidx.annotation.LayoutRes
import androidx.annotation.MainThread
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.*
import com.harvest.scientific.ladder.ext.launchOnMain
import io.reactivex.Single
import io.reactivex.SingleEmitter

abstract class BaseFragment(@LayoutRes contentLayoutId: Int = 0) : Fragment(contentLayoutId),
    ILoading {
        
    companion object {
        const val TAG = "BaseFragment"
    }

    protected var isViewCreated = false
    protected val viewCreatedSingleEmitters by lazy { mutableListOf<SingleEmitter<Boolean>>() }
    private var containerId = 0

    fun checkSelfPermission(ctx: Context, permissions: Array<String?>): Boolean {
        var isAllGranted = true
        for (permission in permissions) {
            if (ContextCompat.checkSelfPermission(
                    ctx.applicationContext,
                    permission!!
                )
                != PackageManager.PERMISSION_GRANTED
            ) {
                isAllGranted = false
                break
            }
        }
        return isAllGranted
    }

    override fun dismissLoading() {
    }

    override fun showLoading() {
    }

    open fun onKeyEvent(keyCode: Int?, event: KeyEvent?): Boolean? {
        return false
    }

    protected open fun isActive(): Boolean {
        return null != activity && activity?.isFinishing == false
    }

    override fun onDestroyView() {
        super.onDestroyView()
    }

    @CallSuper
    @MainThread
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        isViewCreated = true
        launchOnMain(1) {
            viewCreatedSingleEmitters.forEach {
                if (!it.isDisposed) it.onSuccess(false)
            }
            viewCreatedSingleEmitters.clear()
        }
    }

    protected fun withViewCreated(): Single<Boolean> {
        return Single.create {
            if (isViewCreated) {
                if (isActive()) {
                    it.onSuccess(true)
                }
            } else {
                viewCreatedSingleEmitters.add(it)
            }
        }
    }


    
    open fun getContainerId(): Int {
        return containerId
    }

    open fun setContainerId(containerId: Int) {
        this.containerId = containerId
    }

    override fun onResume() {
        super.onResume()
        if (userVisibleHint) {
            onUserVisibleChanged(true)
        }
    }

    override fun onPause() {
        super.onPause()
    }

    override fun onDetach() {
        super.onDetach()
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isResumed) {
            onUserVisibleChanged(isVisibleToUser)
        }
    }

    open fun onUserVisibleChanged(isVisibleToUser: Boolean) {

    }

    open fun isVisibleToUser(): Boolean {
        return isResumed && userVisibleHint
    }
}

inline fun <reified VM : ViewModel> Fragment.viewModelFromActivity() =
    viewModels<VM>({ requireActivity() })